home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Mac Game Programming Gurus
/
TricksOfTheMacGameProgrammingGurus.iso
/
Book Chapters
/
07 - Mechanics - Environment
/
Maze
/
Maze.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-12
|
5KB
|
206 lines
/*
Maze demo
by Ingemar Ragnemalm 1995
Demonstrates how to make a (constrained) distance transform for
finding the shortest path through a maze.
*/
/*Size of the array*/
#define kArraySizeH 15
#define kArraySizeV 12
/*Size of the tiles*/
#define kTileSizeH 24
#define kTileSizeV 24
/* What does each tile contain? The destination is zero
(more than one is permitted!), and the outermost enties
must always be walls (-1). Edit this to try other layouts! */
short tileArray[kArraySizeH][kArraySizeV] = {
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{-1,999,999,999, -1, -1, -1, -1, -1, -1,999, -1},
{-1,999, 0,999, -1, -1, -1, -1, -1, -1,999, -1},
{-1,999,999,999,999,999,999,999,999,999,999, -1},
{-1,999, -1,999, -1, -1,999,999,999, -1, -1, -1},
{-1, -1, -1,999, -1, -1,999, -1, -1, -1, -1, -1},
{-1, -1, -1,999, -1, -1,999, -1, -1, -1, -1, -1},
{-1, -1,999,999,999,999,999,999,999,999,999, -1},
{-1, -1,999,999, -1, -1, -1, -1, -1, -1,999, -1},
{-1, -1,999,999, -1, -1, -1, -1, -1, -1,999, -1},
{-1, -1, -1,999,999,999,999,999, -1, -1,999, -1},
{-1, -1, -1,999,999,999,999,999, -1, -1,999, -1},
{-1, -1, -1, -1, -1,999,999,999,999,999,999, -1},
{-1, -1, -1, -1, -1,999,999,999, -1, -1, -1, -1},
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
};
/*All 8 directions as vectors*/
Point directionTable[8] =
{
{-1, 1 },
{-1, 0 },
{-1,-1 },
{ 0,-1 },
{ 1,-1 },
{ 1, 0 },
{ 1, 1 },
{ 0, 1 }
};
/* Pictures*/
PicHandle wallTile;
/* A boolean for signalling if a change is made */
Boolean changeFlag;
/* Draw a tile */
static void DrawTile(short h, short v)
{
Rect tileRectangle;
Str255 tempString;
SetRect(&tileRectangle, h * kTileSizeH, v * kTileSizeV, (h + 1) * kTileSizeH, (v + 1) * kTileSizeV);
if (tileArray[h][v] < 0)
DrawPicture(wallTile, &tileRectangle);
else
{
EraseRect(&tileRectangle);
MoveTo(h * kTileSizeH + 5, v * kTileSizeV + 18);
NumToString(tileArray[h][v], tempString);
DrawString(tempString);
}
} /*DrawTile*/
void DrawAllTiles()
{
short h, v;
for ( h = 0 ; h < kArraySizeH ; h++)
for ( v = 0 ; v < kArraySizeV ; v++)
DrawTile(h, v);
}
/* Standard inits */
static void InitToolbox(void) {
InitGraf (&qd.thePort);
InitFonts ();
FlushEvents (everyEvent,0);
InitWindows ();
InitMenus ();
TEInit ();
InitDialogs (nil);
InitCursor ();
} /*InitToolbox*/
void DistanceTransformForward()
{
short h, v;
short direction;
Point neighbor;
for ( v = 0 ; v < kArraySizeV ; v++)
for ( h = 0 ; h < kArraySizeH ; h++)
{
if (tileArray[h][v] > 0)
{
for (direction = 0; direction < 4; direction++)
{
neighbor.h = h + directionTable[direction].h;
neighbor.v = v + directionTable[direction].v;
if (tileArray[neighbor.h][neighbor.v] >= 0)
if (tileArray[neighbor.h][neighbor.v]+1 < tileArray[h][v])
{
tileArray[h][v] = tileArray[neighbor.h][neighbor.v]+1;
changeFlag = true;
}
} // for directions 0..3
} // if >0
} // for all spaces
} /*DistanceTransformForward*/
void DistanceTransformBackward()
{
short h, v;
short direction;
Point neighbor;
for ( v = kArraySizeV ; v >= 0 ; v--)
for ( h = kArraySizeH-1 ; h >= 0 ; h--)
{
if (tileArray[h][v] > 0)
{
for (direction = 4; direction < 8; direction++)
{
neighbor.h = h + directionTable[direction].h;
neighbor.v = v + directionTable[direction].v;
if (tileArray[neighbor.h][neighbor.v] >= 0)
if (tileArray[neighbor.h][neighbor.v]+1 < tileArray[h][v])
{
tileArray[h][v] = tileArray[neighbor.h][neighbor.v]+1;
changeFlag = true;
}
} // for directions 0..3
} // if >0
} // for all spaces
} /*DistanceTransformBackward*/
/****************** Main program ******************/
void main(void) {
WindowPtr myWindow;
Rect windowRectangle;
short h,v;
InitToolbox();
/*Set up the window*/
SetRect(&windowRectangle, 50, 50, 50 + kArraySizeH * kTileSizeH, 50 + kArraySizeV * kTileSizeV);
myWindow = NewCWindow(0L, &windowRectangle, "\pMaze demo", true, 0, (WindowPtr)-1L, false, 0);
SetPort(myWindow);
TextSize(9);
/* Load the picture*/
wallTile = GetPicture(128); /*PICT resource #128.*/
/* Redraw */
DrawAllTiles();
/* Repeat the distance transform until no more changes occur! */
do
{
changeFlag = false;
/* Forward scan */
DistanceTransformForward();
DrawAllTiles();
/* Backward scan */
DistanceTransformBackward();
DrawAllTiles();
}
while (changeFlag);
/* Signal completion */
SysBeep(1);
while ( ! Button () )
;
} /*Maze*/